#include "FeatureExtractor.h"
#include <iostream>
#include <cmath>

std::vector<double> extractHuMoments(const cv::Mat& image) {
    // 转换为灰度图像
    cv::Mat grayImg;
    cv::cvtColor(image, grayImg, cv::COLOR_BGR2GRAY);
 
    // 计算Hu矩
    cv::Moments moments = cv::moments(grayImg);
    cv::Mat hu;
    cv::HuMoments(moments, hu);
 
    // 处理Hu矩数值
    std::vector<double> processedHuMoments;
    for (int i = 0; i < 7; ++i) {
        double val = hu.at<double>(i);
        processedHuMoments.push_back(
            std::copysign(1.0, val) * std::log10(std::abs(val) + 1e-10)
        );
    }
 
    return processedHuMoments;
}

ChessDatabase::ChessPiece extractChessPieceFeatures(
    const std::string& imagePath,
    double x,
    double y,
    const std::string& type)
{
    // 加载图像（彩色模式）
    cv::Mat img = cv::imread(imagePath, cv::IMREAD_COLOR);
    if (img.empty()) {
        throw std::runtime_error("无法加载图像: " + imagePath);
    }
   // cv::imshow("Image Display", img);
    //cv::waitKey(0);

    // 转换为 HSV 空间
    cv::Mat hsvImg;
    cv::cvtColor(img, hsvImg, cv::COLOR_BGR2HSV);

    // 判断颜色（红色或黑色）
    const int minSaturation = 40;  // 最小饱和度阈值
    const int minValue = 30;       // 最小亮度阈值
    const float redThreshold = 0.3; // 红色像素比例阈值

    int redCount = 0;
    int validPixels = 0;

    // 遍历所有像素
    for (int i = 0; i < hsvImg.rows; ++i) {
        for (int j = 0; j < hsvImg.cols; ++j) {
            cv::Vec3b hsv = hsvImg.at<cv::Vec3b>(i, j);

            // 过滤无效像素（低饱和度或低亮度）
            if (hsv[1] > minSaturation && hsv[2] > minValue) {
               ++validPixels;

                // Hue值范围处理（OpenCV将Hue缩放到0-180）
                if ((hsv[0] <= 10) || (hsv[0] >= 160)) { // 红色范围
                    ++redCount;
                }
            }
        }
    }

    // 打印调试信息
    std::cout << "图像总像素数: " << img.total() << std::endl;
    std::cout << "有效像素数 (validPixels): " << validPixels << std::endl;
    std::cout << "红色像素数 (redCount): " << redCount << std::endl;

/*
    // 有效像素比例不足时抛出异常
    if (validPixels < img.total() * 0.1) {
        throw std::runtime_error("图像有效颜色区域不足");
    }
*/
    // 计算红色像素比例
    float redRatio = static_cast<float>(redCount) / validPixels;
    std::string color = redRatio > redThreshold ? "red" : "black";

    std::cout << "红色像素比例 (redRatio): " << redRatio << std::endl;
    std::cout << "识别颜色: " << color << std::endl;

// 调用封装后的Hu矩提取函数
    std::vector<double> huMoments = extractHuMoments(img);

    // 构造棋子特征对象
    ChessDatabase::ChessPiece piece;
    piece.x = x;
    piece.y = y;
    piece.color = color; // 自动识别的颜色
    piece.type = type;

// 将提取的Hu矩复制到结构体中
    for (int i = 0; i < 7; ++i) {
        piece.huMoments[i] = huMoments[i];
    }
	
    return piece;
}

//多态特征提取，这个可以输入图像也可以（输入mat不是path）
ChessDatabase::ChessPiece extractChessPieceFeatures(
    cv::Mat img,
    double x,
    double y,
    const std::string& type)
{
// 验证输入图像有效性
    if (img.empty()) {
        throw std::runtime_error("输入图像为空");  // 修改2：更新错误提示
    }
    
   // cv::imshow("Image Display", img);
   // cv::waitKey(0);

    // 转换为 HSV 空间
    cv::Mat hsvImg;
    cv::cvtColor(img, hsvImg, cv::COLOR_BGR2HSV);

    // 判断颜色（红色或黑色）
    const int minSaturation = 40;  // 最小饱和度阈值
    const int minValue = 30;       // 最小亮度阈值
    const float redThreshold = 0.3; // 红色像素比例阈值

    int redCount = 0;
    int validPixels = 0;

    // 遍历所有像素
    for (int i = 0; i < hsvImg.rows; ++i) {
        for (int j = 0; j < hsvImg.cols; ++j) {
            cv::Vec3b hsv = hsvImg.at<cv::Vec3b>(i, j);

            // 过滤无效像素（低饱和度或低亮度）
            if (hsv[1] > minSaturation && hsv[2] > minValue) {
               ++validPixels;

                // Hue值范围处理（OpenCV将Hue缩放到0-180）
                if ((hsv[0] <= 10) || (hsv[0] >= 160)) { // 红色范围
                    ++redCount;
                }
            }
        }
    }

    // 打印调试信息
    std::cout << "图像总像素数: " << img.total() << std::endl;
    std::cout << "有效像素数 (validPixels): " << validPixels << std::endl;
    std::cout << "红色像素数 (redCount): " << redCount << std::endl;

/*
    // 有效像素比例不足时抛出异常
    if (validPixels < img.total() * 0.1) {
        throw std::runtime_error("图像有效颜色区域不足");
    }
*/
    // 计算红色像素比例
    float redRatio = static_cast<float>(redCount) / validPixels;
    std::string color = redRatio > redThreshold ? "red" : "black";

    std::cout << "红色像素比例 (redRatio): " << redRatio << std::endl;
    std::cout << "识别颜色: " << color << std::endl;

// 调用封装后的Hu矩提取函数
    std::vector<double> huMoments = extractHuMoments(img);

    // 构造棋子特征对象
    ChessDatabase::ChessPiece piece;
    piece.x = x;
    piece.y = y;
    piece.color = color; // 自动识别的颜色
    piece.type = type;

// 将提取的Hu矩复制到结构体中
    for (int i = 0; i < 7; ++i) {
        piece.huMoments[i] = huMoments[i];
    }
	
    return piece;
}